<template>
  <a-layout>
    <a-layout-header class="layout-header">
      <a-space class="operate-btn-group">
        <a-button
          type="link"
          style="margin-left: -24px"
          @click="$router.push('/')"
        >
          <template #icon>
            <ArrowLeftOutlined />
          </template>
          <span>返回</span>
        </a-button>
        <!-- <a-button type="primary" @click="jsonModalVisible = true">
          解析json
        </a-button>
        <a-button type="primary" @click="axureModalVisible = true">
          解析axure
        </a-button> -->
      </a-space>
      <a-space class="operate-btn-group">
        <a-select
          style="width: 220px"
          :options="formTemplateList"
          v-model:value="templateFile"
        />
        <a-button type="primary" @click="handlePreviewCode">代码预览</a-button>
        <a-button type="primary" @click="handlePreviewMetaCode"
          >查看元数据</a-button
        >
      </a-space>
    </a-layout-header>
    <a-layout-content>
      <a-layout has-sider>
        <a-layout-sider>
          <ComponentMenu />
        </a-layout-sider>
        <a-layout-content>
          <div class="form-generator-wrapper">
            <component
              :is="CurrentFormComponent"
              :layoutConfig="globalConfig.layoutConfig"
              :formFields="fieldList"
              @selectField="handleSelectRecord"
            />
          </div>
        </a-layout-content>
        <a-layout-sider class="right" width="300px">
          <AttrSettings :globalConfig="globalConfig" :record="currentRecord" />
        </a-layout-sider>
      </a-layout>
    </a-layout-content>
  </a-layout>
  <JsonModal
    v-model:modelValue="jsonModalVisible"
    @resolveJson="handleResolveJson"
  />
  <AxureModal v-model:modelValue="axureModalVisible" />
  <PreviewCode
    v-model:modelValue="codeModalVisible"
    :templateFile="templateFile"
    :codeObj="codeObj"
  />
</template>
<script setup>
import { ref, provide, computed, watch } from "vue";
import { storeToRefs } from "pinia";
import { useFormStore } from "@/store/form";
import { ArrowLeftOutlined } from "@ant-design/icons-vue";

import AxureModal from "./components/AxureModal/index.vue";
import AntdPreviewForm from "./components/PreviewForm/AntdForm/index.vue";
import ElementPreviewForm from "./components/PreviewForm/ElementForm/index.vue";
import PreviewCode from "./components/PreviewCode/index.vue";
import ComponentMenu from "./components/ComponentMenu/index.vue";
import AttrSettings from "./components/AttrSettings/index.vue";
import JsonModal from "./components/JsonModal/index.vue";
import { genCode } from "./util/genCode";

const formTemplateList = ref([]);
const modules = import.meta.glob("./template/form/*.vue", { as: "raw" });
for (const path in modules) {
  modules[path]().then((mod) => {
    const fileName = /\.\/template\/form\/([\w\-]+)\.vue/.exec(path)?.[1] ?? "";
    formTemplateList.value.push({
      label: fileName,
      value: fileName,
    });
  });
}

const store = useFormStore();

const { templateFile, globalConfig, fieldList } = storeToRefs(store);
const CurrentFormComponent = computed(() => {
  return store.isElement ? ElementPreviewForm : AntdPreviewForm;
});
watch(
  () => templateFile.value,
  () => {
    store.setTemplateFile(templateFile.value);
  }
);

function handleAdd(field, index = fieldList.length) {
  console.log("handleAdd", field, index);
  if (fieldList.value.length === 0) {
    fieldList.value.push(field);
  } else {
    fieldList.value.splice(index, 0, field);
  }
}
function handleDel(index) {
  console.log("handleDel", index);
  fieldList.value.splice(index, 1);
}

provide("fieldListTools", {
  add: handleAdd,
  del: handleDel,
  swap(oldIndex, newIndex) {
    console.log("handleSwap", oldIndex, newIndex);
    const [field] = fieldList.value.splice(oldIndex, 1);
    fieldList.value.splice(newIndex, 0, field);
  },
});

// json解析
const jsonModalVisible = ref(false);
function handleResolveJson(fields) {
  fieldList.value = [...fields];
}

// 代码预览
const codeObj = ref({});
const codeModalVisible = ref(false);
async function handlePreviewCode() {
  if (fieldList.value.length > 0) {
    codeObj.value = await genCode(globalConfig.value, fieldList.value);
    codeModalVisible.value = true;
  }
}

function handlePreviewMetaCode() {
  codeObj.value["App.vue"] = JSON.stringify(fieldList.value, null, 2);
  codeModalVisible.value = true;
}

const defaultRecord = { rules: {} };
const currentRecord = ref({ ...defaultRecord });
function handleSelectRecord(record) {
  currentRecord.value = record || { ...defaultRecord };
}

const axureModalVisible = ref(false);
</script>

<style lang="less" scoped>
@header-height: 60px;
@border-style:1px solid #ddd;

.ant-layout .ant-layout-header {
  height: @header-height;
  line-height: @header-height;
  background: #fff !important;
  border-bottom: @border-style;
  padding: 0 20px;
  .operate-btn-group {
    height: 100%;
  }
}

.ant-layout .ant-layout-content {
  height: calc(100vh - @header-height);
}

.ant-layout .ant-layout-sider {
  height: calc(100vh - @header-height);
  background: #fff !important;
  border-right: @border-style;
  overflow: "auto";
  position: "fixed";
  left: 0;
  top: 0;
  bottom: 0;
  &.right {
    right: 0;
    border-right: none;
    border-left: @border-style;
  }
}

.form-generator-wrapper {
  box-sizing: border-box;
  padding: 15px 10px;
  height: 100%;
}
.layout-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
